package caixb;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigInteger;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.fram.common.exception.ProException;
import com.fram.common.exception.ProValiDataException;
import com.fram.common.util.PublicMethod;
import com.fram.common.util.date.DateUtils;

public class TCPService {

	public static final String SERVICE_IP = "127.0.0.1";
	// public static final String SERVICE_IP = "192.168.0.235";

	public static final int SERVICE_PORT = 8198;

	public static final char END_CHAR = '#';

	public static void main(String[] args) {
		TCPService service = new TCPService();
		service.startService();
	}

	private void startService() {
		try {
			InetAddress address = InetAddress.getByName(SERVICE_IP);
			Socket connect = null;
			ExecutorService pool = Executors.newFixedThreadPool(5);
			try (ServerSocket service = new ServerSocket(SERVICE_PORT, 5, address)) {
				while (true) {
					connect = service.accept();
					// 创建一个任务
					ServiceTask serviceTask = new ServiceTask(connect);
					// 放入线程池等待运行
					pool.execute(serviceTask);
				}
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				if (connect != null)
					connect.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	class ServiceTask implements Runnable {
		private Socket socket;

		ServiceTask(Socket socket) {
			this.socket = socket;
		}

		@Override
		public void run() {
			InputStream in = null;
			OutputStream out = null;
			try {
				in = socket.getInputStream();
				out = socket.getOutputStream();
				System.err.println("====================================================================================");
				System.out.println("-时间->" + DateUtils.DF_SEPARATE_SSS.get().format(new Date()) + "-连接用户->" + socket);

				String startStr = "fa";
				String endStr = "f5";

				byte[] buf = new byte[256];
				in.read(buf);
				String str16 = binary(buf, 16);
				str16 = str16.toLowerCase();
				// System.out.println("-时间->" + DateUtils.DF_SEPARATE_SSS.get().format(new Date()) + "-请求所有参数2进制->" + binary(buf, 2));
				System.out.println("-时间->" + DateUtils.DF_SEPARATE_SSS.get().format(new Date()) + "-请求所有参数16进制->" + str16);
				String param = str16.substring(0, str16.indexOf(endStr) + 2);
				System.out.println("-时间->" + DateUtils.DF_SEPARATE_SSS.get().format(new Date()) + "-请求参数16进制->" + param);
				int len = param.length() / 2;
				String lenStr16 = PublicMethod.numberComplementUpZero(Integer.toHexString(len), 2);
				if (param.length() <= 26) {
					System.err.println("-时间->" + DateUtils.DF_SEPARATE_SSS.get().format(new Date()) + "-长度验证失败 小于26位->");
					throw new ProValiDataException("长度验证失败 小于26位");
				}
				String paramLenStr16 = param.substring(24, 26);
				System.out.println(
						"-时间->" + DateUtils.DF_SEPARATE_SSS.get().format(new Date()) + "-请求参数长度验证->" + len + "-lenStr16->" + lenStr16 + "-paramLenStr16->" + paramLenStr16);
				if (!paramLenStr16.equals(lenStr16)) {
					System.err.println("-时间->" + DateUtils.DF_SEPARATE_SSS.get().format(new Date()) + "-长度验证失败->" + paramLenStr16);
					throw new ProValiDataException("长度验证失败");
				}
				String paramCrcStr = param.substring(param.length() - 6, param.length() - 2);
				String crcStr = CRC16.getCRC(TCPService.HexStringToBinary(param.substring(0, param.length() - 6)));
				System.out.println("-时间->" + DateUtils.DF_SEPARATE_SSS.get().format(new Date()) + "-请求参数CRC验证-crcStr->" + crcStr + "-paramCrcStr->" + paramCrcStr);
				if (!crcStr.equals(paramCrcStr)) {
					System.err.println("-时间->" + DateUtils.DF_SEPARATE_SSS.get().format(new Date()) + "-CRC验证失败-");
					throw new ProValiDataException("CRC验证失败");
				}
				// 请求城市农场项目 做处理

				StringBuffer response = new StringBuffer();
				response.append(startStr);
				response.append(param.substring(10, 18));
				response.append(param.substring(2, 10));
				response.append((param.substring(18, 20).equals("a0") ? "a1" : "a0"));
				response.append("01");
				// 控制参数
				String message = "01071e000064";
				// 计算长度
				len = response.length() / 2 + message.length() / 2 + 5;
				response.append("00");
				String respLenStr = Integer.toHexString(len);
				response.append(PublicMethod.numberComplementUpZero(respLenStr, 2));
				response.append(message);
				response.append(CRC16.getCRC(TCPService.HexStringToBinary(response.toString())));
				response.append(endStr);
				System.out.println("-时间->" + DateUtils.DF_SEPARATE_SSS.get().format(new Date()) + "-响应参数->" + response);

				out.write(HexStringToBinary(response.toString()));

				System.out.println("-时间->" + DateUtils.DF_SEPARATE_SSS.get().format(new Date()) + "-响应成功->" + response);
			} catch (ProException e) {
				try {
					out.write(e.getErrorMsg().getBytes());
					System.err.println("-时间->" + DateUtils.DF_SEPARATE_SSS.get().format(new Date()) + "-响应成功->" + e.getErrorMsg());
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				if (socket != null) {
					try {
						socket.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				if (out != null) {
					try {
						out.close();
					} catch (Exception e2) {
						e2.printStackTrace();
					}
				}
				if (in != null) {
					try {
						in.close();
					} catch (Exception e2) {
						e2.printStackTrace();
					}
				}
			}
		}
	}

	/**
	 * 将byte[]转为各种进制的字符串
	 * 
	 * @param bytes
	 *            byte[]
	 * @param radix
	 *            基数可以转换进制的范围，从Character.MIN_RADIX到Character.MAX_RADIX，超出范围后变为10进制
	 * @return 转换后的字符串
	 */
	public static String binary(byte[] bytes, int radix) {
		return new BigInteger(1, bytes).toString(radix);// 这里的1代表正数
	}

	/**
	 * 将二进制转换成16进制
	 * 
	 * @param buf
	 * @return
	 */
	public static String parseByte2HexStr(byte buf[]) {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < buf.length; i++) {
			String hex = Integer.toHexString(buf[i] & 0xFF);
			if (hex.length() == 1) {
				hex = '0' + hex;
			}
			sb.append(hex.toUpperCase());
		}
		return sb.toString();
	}

	private static String hexStr = "0123456789abcdef";

	/**
	 * 
	 * @param hexString
	 * @return 将十六进制转换为字节数组
	 */
	public static byte[] HexStringToBinary(String hexString) {
		// hexString的长度对2取整，作为bytes的长度
		int len = hexString.length() / 2;
		byte[] bytes = new byte[len];
		byte high = 0;// 字节高四位
		byte low = 0;// 字节低四位

		for (int i = 0; i < len; i++) {
			// 右移四位得到高位
			high = (byte) ((hexStr.indexOf(hexString.charAt(2 * i))) << 4);
			low = (byte) hexStr.indexOf(hexString.charAt(2 * i + 1));
			bytes[i] = (byte) (high | low);// 高地位做或运算
		}
		return bytes;
	}

}